package com.sgfm.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sgfm.client.ClientContains;
import com.sgfm.client.ClientsSender;
import com.sgfm.event.entity.Event;
import com.sgfm.event.processor.EventProcessor;
import com.sgfm.event.processor.Processor;
import com.sgfm.util.PropertyUtils;
import com.sgfm.util.XmlDataUtils;

public class EventServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	private Processor processor = null;
	
	private ClientsSender sender;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String ipAddress = getIpAddress(request);
		if (isConfigIp(ipAddress)) {
			doResponseMessage(response);
			String requestData = get(request);
			processRequest(requestData);
		}else{
			processIllegalRequest(response);
		}
	}

	private void processIllegalRequest(HttpServletResponse response) {
		response.setStatus(403);
	}

	private boolean isConfigIp(String ipAddress) {
		return ipAddress.equals(PropertyUtils.getValue("rest_callback_addr"));
	}

	private void processRequest(String requestData) {
		String eventName = XmlDataUtils.getValueByName(requestData, "event");
		this.processor = createProcess(requestData);
		switch (Event.getEvent(eventName)) {
		case INCOMINGCALL:
			processor.doIncomingCall(); break;
		case DIRECTBEGINRPT:
			processor.doDirectBegin(); break;
		case CALLBACKBEGINRPT:
			processor.doCallBackBegin(); break;
		case INCOMINGCALLACK:
			processor.doIncomingCallack(); break;
		case CALLSTATRPT:
			processor.doCallStat(); break;
		case DIRECTTOSERVICE:
			processor.doDirectToService(); break;
		case PREDICTOUTCALLBEGINRPT:
			processor.doPreDictOutCallBegin(); break;
		case CALLDISCONNECTRPT:
			processor.doCallDisConnect(); break;
		case CALLENQUEUESUCCRPT:
			processor.doCallEnQueueSucc(); break;
		case CALLENQUEUEOVERFLOWRPT:
			processor.doCallEnQueueOverFlow(); break;
		case CALLDEQUEUERPT:
			processor.doCallDequeue(); break;
		case HOLDBEGIN:
			processor.doHoldBegin(); break;
		case HOLDEND:
			processor.doHoldEnd(); break;
		case TRANSFERSUCCESS:
			processor.doTransferSuccess(); break;
		case TRANSFERFAILE:
			processor.doTransferFaile(); break;
		case CONSULTBEGIN:
			processor.doConsultBegin(); break;
		case CONSULTFAILE:
			processor.doConsultFaile(); break;
		case CONSULTEND:
			processor.doConsultEnd(); break;
		case IVRREPORTDTMF:
			processor.doIvrReportDtmf(); break;
		case IVRPLAYOVERRPT:
			processor.doIvrPlayOver(); break;
		case CALLSERVICEDTMF:
			processor.doCallServiceDtmf(); break;
		case CALLBILLRPT:
			processor.doCallBill(); break;
		case CACCSTATERPT:
			processor.doCaccState(); break;
		case EAVESDROPRPT:
			processor.doEavesDrop(); break;
		case CALLLEAVEENDRPT:
			processor.doCallLeaveEnd(); break;
		case IPCCRINGAUDIT:
			processor.doIpccRingAudit(); break;
		default:
			processor.doKnow();
		}
	}

	private Processor createProcess(String requestData) {
		return new EventProcessor(requestData, this.sender);
	}

	private String get(HttpServletRequest request) {
		String data = "";
		byte[] buffer = new byte[1024];
		InputStream in = null;
		int len = -1;
		try {
			in = request.getInputStream();
			while ((len = in.read(buffer)) != -1) {
				data = new String(buffer, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}

	private void doResponseMessage(HttpServletResponse response) {
		try {
			String template = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><response><retcode>0</retcode><reason>0</reason></response>";
			PrintWriter writer = response.getWriter();
			writer.write(template);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private String getIpAddress(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		if (ip.endsWith("0:0:0:0:0:0:1")) {
			ip = "127.0.0.1";
		}
		return ip;
	}

	@Override
	public void init() throws ServletException {
		if (this.sender == null) {
			this.sender = new ClientsSender(new ClientContains());
		}
	}
}
